package com.basin.micro.admin.module.employee.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.basin.common.core.consts.StatusConst;
import com.basin.common.core.exception.BasinException;
import com.basin.common.rabbitmq.support.RabbitmqProducer;
import com.basin.common.rabbitmq.template.SendMsgTemplate;
import com.basin.micro.admin.module.department.service.DepartmentService;
import com.basin.micro.admin.module.employee.pojo.entity.EmployeeEntity;
import com.basin.micro.admin.module.employee.repository.EmployeeRepository;
import com.basin.micro.admin.module.employee.service.EmployeeService;
import com.basin.micro.admin.module.position.service.PositionService;
import com.basin.micro.admin.support.EmpIdGenerator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author: Sam ZHONG | sammy1997@aliyun.com
 */
@Service
@RequiredArgsConstructor
@Slf4j(topic = "BASIN:ADMIN:EMPLOYEE_SERVICE")
public class EmployeeServiceImpl implements EmployeeService {
    private static final String TAG_POSITION = "position";
    private static final String TAG_DEPT = "dept";

    private final DepartmentService departmentService;
    private final PositionService positionService;
    private final EmployeeRepository employeeRepository;

    private final RabbitmqProducer rabbitmqProducer;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean add(EmployeeEntity entity) {
        // check
        String deptCode = entity.getDeptCode();
        checkRelCodeExists(deptCode, TAG_DEPT);
        String positionCode = entity.getPositionCode();
        checkRelCodeExists(positionCode, TAG_POSITION);
        // code & id
        String empName = entity.getEmpName();
        String empCode = PinyinUtil.getPinyin(empName, "");
        long codeCount = employeeRepository.count(Wrappers.<EmployeeEntity>lambdaQuery()
                .eq(EmployeeEntity::getEmpName, empName)
                .in(EmployeeEntity::getStatus, StatusConst.DISABLE, StatusConst.ENABLE));
        entity.setEmpCode(empCode + (++codeCount));
        long totalCount = employeeRepository.count(Wrappers.<EmployeeEntity>lambdaQuery()
                .in(EmployeeEntity::getStatus, StatusConst.DISABLE, StatusConst.ENABLE));
        entity.setEmpId(EmpIdGenerator.generateEmpId(totalCount));
        boolean save = employeeRepository.save(entity);
        if (save) {
            this.rabbitmqProducer.<String>send(
                    new SendMsgTemplate<>() {{
                        setExchange("auth_exchange");
                        setRoutingKey("emp_init_authorized");
                        setMessage(entity.getEmpId());
                    }}
            );
        }
        return save;
    }

    @Override
    public List<EmployeeEntity> getEmpByCode(Collection<String> emps) {
        if (ObjectUtil.isEmpty(emps)) return new ArrayList<>();
        return this.employeeRepository.list(Wrappers.<EmployeeEntity>lambdaQuery()
                .in(EmployeeEntity::getEmpCode, emps));
    }

    private void checkRelCodeExists(String code, String tag) {
        int count = 0;
        if (TAG_DEPT.equalsIgnoreCase(tag)) {
            count = this.departmentService.getByCode(code) == null ? 0 : 1;
        }
        if (TAG_POSITION.equalsIgnoreCase(tag)) {
            count = this.positionService.getByCode(code) == null ? 0 : 1;
        }
        if (count == 0) {
            throw new BasinException("所选的" +
                    (TAG_DEPT.equalsIgnoreCase(tag) ? "部门" : "职位") +
                    "[" + code + "]不存在");
        }
    }
}
